﻿using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.Net.Sockets;

public class GameManager : MonoBehaviour {

	public GameObject winParticles;
	public Texture2D mapTexture;

	private static GameManager instance = null;

	private int status;
	private int finishFlag;
	private string[,] cubeNames;
	private bool[,] level;
	private bool[,] currLevelProgress;
	private delegate void CubeNotifications(int x, int y);
	private delegate void ResetNotifications();
	private CubeNotifications cubeN;
	private ResetNotifications resetN;

	// int level;

	void Awake () {
		if (instance == null) {
			instance = this;
			Debug.Log("Initialized GM");
		} else if (instance != this) {
			Destroy(gameObject);
		}

		Init ();
	}

	void Start() {
		GameManager.getInstance ().SetStatus (341);
	}

	public void InitUI() {
	}

	void Init() {
		cubeNames = new string[,] {{"CubeUL", "CubeU", "CubeUR"},
								   {"CubeL",  "Cube",  "CubeR"},
								   {"CubeBL", "CubeB", "CubeBR"}};

		level = new bool[3, 3];

		currLevelProgress = new bool[3, 3];
		for (int i = 0; i < 3; i++) {
			for(int j = 0; j < 3; j++) {
				level[i,j] = false;
			}
		}
		status = 0;
		finishFlag = 0;
	}
	
	public static GameManager getInstance() {
		return instance;
	}

	public string getCubeName(int tag) {
		if (!cubeTagWithinRange (tag))
			return null;

		return cubeNames[tag/10, tag%10];
	}

	public bool getCubeStartConfig(int tag) {
		Debug.Log ("Loading starting config ~> " + tag);
		if (!cubeTagWithinRange (tag))
			return false;

		return level[tag/10, tag%10];
	}

	public void CubeClicked(int tag) {
		if (!cubeTagWithinRange (tag))
			return;
		cubeN (tag / 10, tag % 10);
		CheckGameOver ();
	}

	public void CubeUpdateState(int tag, bool on) {

		if (!cubeTagWithinRange (tag))
			return;

		currLevelProgress [tag / 10, tag % 10] = on;
	}

	public void SetStatus(int newStatus) {
		Debug.Log ("Settin Status ~> " + newStatus);
		this.status = newStatus;
		for (int i = 0; i < 3; i++) {
			for(int j = 0; j < 3; j++) {
				level[i,j] = ((newStatus % 2) == 1);
				newStatus >>= 1;
			}
		}
	}

	public int GetOriginalStatus() {
		return this.status;
	}

	public int GetCurrentStatus() {
		int retStatus = 0;
		for (int i = 0; i < 3; i++) {
			for(int j = 0; j < 3; j++) {
				retStatus += ((level[i,j]) ? 1 : 0);
				retStatus <<= 1;
			}
		}
		return retStatus;
	}

	public int GetFinished() {
		return finishFlag;
	}

	public void CheckGameOver() {

		if (finishFlag != 0)
			return; // the flag for game over has already been set

		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				if (!currLevelProgress [i, j]) {
					finishFlag = 0;
					return;
				}
			}
		}
		finishFlag = 1;
		// game is over, play win message and particles
// 		returnButton.GetComponent<Text> ().text = "Continue";
//		winMessage.SetActive (true);
//		returnButton.SetActive (false);
// 		Instantiate (winParticles, transform.position, Quaternion.identity);
	}

	public void Reset() {
		Debug.Log ("Reset Called");
		finishFlag = 0;
// 		returnButton.SetActive (true);
		winParticles = null;
		SetStatus (this.status);
		resetN ();
	}

	public void Return() {
		if (finishFlag == 0) {
			finishFlag = -1;
		}
	}

	public void registerForCubeNotifications(ICube obj) {
		cubeN += obj.CheckAdjacent;
		resetN += obj.Reset;
	}

	public void deregisterForCubeNotifications(ICube obj) {
		cubeN -= obj.CheckAdjacent;
		resetN -= obj.Reset;
	}

	private bool cubeTagWithinRange(int tag) {
		if (tag < 0)
			return false;
		if (tag / 10 > 2 || tag % 10 > 2)
			return false;

		return true;
	}
	void OnLevelWasLoaded(int level) {
		if (level == 3) {
			GameObject.Find ("Map").GetComponent<Renderer> ().material.mainTexture = mapTexture;
		} else if (level == 2) {
		}
	}
}
